package com.novoda.runbuddy.provider;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

import com.novoda.runbuddy.R;
import com.novoda.runbuddy.model.Route;
import com.novoda.runbuddy.service.CannedRunManagerImpl;
import com.novoda.runbuddy.util.DBUtil;

public class ContentProviderRouteTest extends AndroidTestCase {

	private SQLiteDatabase		mdb;
	private static final String	TAG						= ContentProviderRouteTest.class.getName();
	private static final String	RUN_BUDDY_DB			= "runBuddyDB1.db";
	private static final String	URItoGetRoute1Details	= RunBuddyCP.Routes.CONTENT_URI + "/1";

	private static final long	ROUTE1_LATITUDE			= 55851100;
	private static final long	ROUTE1_CENTER_LONGITUDE	= -4233360;
	private static final long	ROUTE1_CENTER_LATITUDE	= 55849004;
	private static final String	ROUTE1_ROUTE_NAME		= "Green PArk";

	private DBUtil				dbUtil					= null;

	protected void setUp() {
		if (dbUtil == null) {
			dbUtil = new DBUtil(this.getContext(), RUN_BUDDY_DB);
		}
		dbUtil.executeDB(R.raw.db_drop);
		dbUtil.createDB();
		dbUtil.insertValuesIntoDB();
		mdb = dbUtil.getDatabase();
		if (mdb == null)
			mdb = getContext().openOrCreateDatabase(RUN_BUDDY_DB, Context.MODE_PRIVATE, null);
	}

	public void testGettingTheFirstRoutesNameFromAQueryForAllRoutes() {
		String routeName = null;
		String[] cols_names = new String[] { RunBuddyCP.Routes.NAME };
		Cursor cur = getContext().getContentResolver().query(RunBuddyCP.Routes.CONTENT_URI, cols_names, null, null, null);
		assertNotNull(cur);
		cur.moveToFirst();
		routeName = cur.getString(0);

		cur.close();
		assertEquals(ROUTE1_ROUTE_NAME, routeName);
	}

	public void testGettingTheFirstRoutesLatitudeFromAQueryForAllRoutes() {
		long routeLatitude = 0;
		String[] cols_latitude = new String[] { RunBuddyCP.Routes.LATITUDE };
		Cursor cur = getContext().getContentResolver().query(RunBuddyCP.Routes.CONTENT_URI, cols_latitude, null, null,
				RunBuddyCP.Routes.DEFAULT_SORT_ORDER);
		assertNotNull(cur);

		cur.moveToFirst();
		routeLatitude = cur.getLong(0);

		cur.close();
		assertEquals(ROUTE1_LATITUDE, routeLatitude);
	}

	public void testGettingRoute1LatitudeAndName() {
		long routeLatitude = 0;
		String[] cols_latitude = new String[] { RunBuddyCP.Routes.NAME, RunBuddyCP.Routes.LATITUDE };
		Cursor cur = getContext().getContentResolver().query(Uri.parse(URItoGetRoute1Details), cols_latitude, null, null,
				RunBuddyCP.Routes.DEFAULT_SORT_ORDER);

		assertNotNull(cur);

		cur.moveToFirst();
		String routeName = cur.getString(0);
		routeLatitude = cur.getLong(1);

		cur.close();
		assertEquals(ROUTE1_LATITUDE, routeLatitude);
		assertEquals(ROUTE1_ROUTE_NAME, routeName);
	}

	public void testInsertingEmptyRoute() {
		Uri uri = getContext().getContentResolver().insert(RunBuddyCP.Routes.CONTENT_URI, null);
		assertEquals(uri.getPathSegments().get(1), "" + 2);
	}

	public void testComputingCenterOfRoute() throws Exception {

		long center_latitude = 0;
		long center_longitude = 0;
		String[] cols_latitude_longitude = new String[] { RunBuddyCP.Routes.LATITUDE, RunBuddyCP.Routes.LONGITUDE };

		// Attach a set of points to new Uri
		dbUtil.executeDB(R.raw.positron_cp_route_insert_route_point_for_route_2);
		Uri uri = getContext().getContentResolver().insert(RunBuddyCP.Routes.CONTENT_URI, null);

		Cursor cur = getContext().getContentResolver().query(uri, cols_latitude_longitude, null, null,
				RunBuddyCP.Routes.DEFAULT_SORT_ORDER);
		cur.moveToFirst();

		center_latitude = cur.getLong(0);
		center_longitude = cur.getLong(1);

		cur.close();
		assertEquals(ROUTE1_CENTER_LATITUDE, center_latitude);
		assertEquals(ROUTE1_CENTER_LONGITUDE, center_longitude);
	}

	public void testGettingTheNumberOfPointsForRoute1() throws Exception {
		Cursor cur = getContext().getContentResolver().query(Uri.parse(GetURIForAllPointsInRoute('1')), null, null, null,
				RunBuddyCP.RoutePoints.DEFAULT_SORT_ORDER);
		int total_no_of_points_in_route1 = 4;
		assertEquals(total_no_of_points_in_route1, cur.getCount());
		cur.close();
	}

	public void testRoutePointsAreDeletedFromRoute1WhenRoute1IsDeleted() throws Exception {
		int route = getContext().getContentResolver().delete(Uri.parse(URItoGetRoute1Details), null, null);
		assertEquals(1, route);

		// Check DB for any routePoints for the above route being deleted. This
		// should be deleted automatically by the trigger
		Cursor cur = mdb.rawQuery("SELECT * from routePoint where _idRoute=1", null);
		assertEquals(0, cur.getCount());
		cur.close();
	}

	public void testInsertingARoutePoint() throws Exception {
		long lat = 21;
		long lon = 22;
		ContentValues values = new ContentValues();
		String[] cols_latitude_longitude = new String[] { RunBuddyCP.RoutePoints.LATITUDE, RunBuddyCP.RoutePoints.LONGITUDE };

		values.put("latitude", lat);
		values.put("longitude", lon);

		assertNotNull(getContext().getContentResolver().insert(Uri.parse(GetURIForAllPointsInRoute('1')), values));

		Cursor cur = getContext().getContentResolver().query(Uri.parse(GetURIForAllPointsInRoute('1')), cols_latitude_longitude,
				null, null, null);
		cur.moveToLast();
		assertEquals(lat, cur.getLong(0));
		cur.close();
	}

	public void testInsertingCannedRoute() throws Exception {

		// insert a canned route
		Route newRoute = CannedRunManagerImpl.loadCannedRoute(getContext(), "Rail Trail", "Rail Trail");
		CannedRunManagerImpl.addRouteToCPDB(mdb, newRoute);

		Cursor cur = getContext().getContentResolver().query(Uri.parse(GetURIForAllPointsInRoute('2')), null, null, null,
				RunBuddyCP.RoutePoints.DEFAULT_SORT_ORDER);
		assertEquals(30, cur.getCount());
		cur.close();

	}
	
	private String GetURIForAllPointsInRoute(char routeId) {
		String URItoGetAllPointsFromARoute = RunBuddyCP.RoutePoints.CONTENT_URI.toString();
		URItoGetAllPointsFromARoute = URItoGetAllPointsFromARoute.replace('#', routeId);
		return URItoGetAllPointsFromARoute;
	}
}
